package cnpm02.j2ee.group3.logic.model;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.event.ValueChangeEvent;
import javax.faces.model.SelectItem;

import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.Create;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Logger;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.log.Log;

import cnpm02.j2ee.group3.logic.dao.impl.CityDao;
import cnpm02.j2ee.group3.logic.dao.impl.FlightDao;
import cnpm02.j2ee.group3.logic.dao.impl.FlightLineDao;
import cnpm02.j2ee.group3.logic.dao.impl.PlaneDao;
import cnpm02.j2ee.group3.logic.dao.impl.TicketDao;
import cnpm02.j2ee.group3.logic.dao.impl.TicketTypeDao;
import cnpm02.j2ee.group3.logic.utils.ATSMUtils;
import cnpm02.j2ee.group3.model.City;
import cnpm02.j2ee.group3.model.Flight;
import cnpm02.j2ee.group3.model.FlightLine;
import cnpm02.j2ee.group3.model.Plane;
import cnpm02.j2ee.group3.model.Ticket;
import cnpm02.j2ee.group3.model.TicketType;
import cnpm02.j2ee.group3.ui.facalets.ModalPanelAction;

@Name("newFlight")
@Scope(ScopeType.PAGE)
public class NewFlight implements Serializable {
	private static final long serialVersionUID = 1L;

	private List<SelectItem> cityFroms = new ArrayList<SelectItem>();
	private List<SelectItem> cityToes = new ArrayList<SelectItem>();
	private List<SelectItem> planes = new ArrayList<SelectItem>();
	private List<String> ticketTypeName = new ArrayList<String>();

	private List<Flight> flights = null;

	// private List<FlightLine> flightLines = null;

	private String selectedCityFrom;
	private String selectedFlightLine;
	private String selectedPlane;
	private Date selectedDepartDate;
	private Date selectedArriveDate;
	private int ticketType1Quantity;
	private int ticketType2Quantity;
	private int ticketType3Quantity;
	private int ticketType4Quantity;
	private long ticketType1Price;
	private long ticketType2Price;
	private long ticketType3Price;
	private long ticketType4Price;
	private long selectedFlightId = -1;

	private int seatCount;
	private String test = "";
	// private Flight selectedFlight;

	@In
	private CityDao cityDao;
	@In
	private FlightLineDao flightLineDao;
	@In
	private PlaneDao planeDao;
	@In
	private FlightDao flightDao;
	@In
	private TicketTypeDao ticketTypeDao;
	@In
	private TicketDao ticketDao;
	@In
	private ATSMUtils atsmUtils;
	@In
	private ModalPanelAction modalPanelAction;
	@Logger
	private Log log;

	public NewFlight() {
		super();
	}

	@Create
	public void init() throws Exception {
		for (Plane p : planeDao.selectAll()) {
			getPlanes().add(
					new SelectItem(String.valueOf(p.getId()), String.valueOf(p
							.getPlaneName()) + " (" + p.getPlaneCode() + ")"));
		}

		for (TicketType ttt : ticketTypeDao.selectAll()) {
			getTicketTypeName().add(atsmUtils.translate(ttt));
		}

		List<FlightLine> flightLines = flightLineDao.selectAll();

		for (FlightLine fl : flightLines) {
			if (!contains(this.cityFroms, fl.getFrom().getId().toString())) {
				this.cityFroms.add(new SelectItem(fl.getFrom().getId()
						.toString(), atsmUtils.translate(fl.getFrom())));
			}
		}
		Collections.sort(cityFroms, new Comparator<SelectItem>() {

			public int compare(SelectItem o1, SelectItem o2) {
				return o1.getLabel().compareTo(o2.getLabel());
			}

		});

		setProperties();
		setDefaultToCityList();
		setDefaultSeatCount((String) getPlanes().get(0).getValue());
	}

	private void setProperties() {
		FacesContext context = FacesContext.getCurrentInstance();
		Map requestParams = context.getExternalContext()
				.getRequestParameterMap();
		if (requestParams.containsKey("selectedFlightId")) {
			long flightId = Long.parseLong(requestParams
					.get("selectedFlightId").toString());
			Flight selectedFlight = flightDao.find(flightId);
			selectedCityFrom = selectedFlight.getFlightLine().getFrom().getId()
					.toString();
			selectedFlightLine = selectedFlight.getFlightLine().getTo().getId()
					.toString();
			selectedPlane = selectedFlight.getPlane().getId().toString();
			selectedDepartDate = selectedFlight.getDepartDate();
			selectedArriveDate = selectedFlight.getArriveDate();

			selectedFlightId = selectedFlight.getId();
		}
	}

	public String beginUpdate() {
		
		return "success";
	}

	public String gotTicket() {
		setTest("got the ticket");
		return "success";
	}

	private boolean contains(List<SelectItem> lst, String id) {
		for (SelectItem si : lst) {
			if (si.getValue().equals(id)) {
				return true;
			}
		}
		return false;
	}

	public void setDefaultToCityList() throws Exception {
		cityToes = new ArrayList<SelectItem>();
		List<FlightLine> flightLines = flightLineDao.selectAll();
		String defaultCityFrom = cityFroms.get(0).getValue().toString();
		for (FlightLine fl : flightLines) {
			if (defaultCityFrom.equals(fl.getFrom().getId().toString())) {
				this.cityToes.add(new SelectItem(fl.getTo().getId().toString(),
						atsmUtils.translate(fl.getTo())));
			}
		}
	}

	public void onChangeCityFrom() throws Exception {
		cityToes = new ArrayList<SelectItem>();
		String from = this.selectedCityFrom;
		List<FlightLine> flightLines = flightLineDao.selectAll();
		for (FlightLine fl : flightLines) {
			if (from.equals(fl.getFrom().getId().toString())) {
				this.cityToes.add(new SelectItem(fl.getTo().getId().toString(),
						atsmUtils.translate(fl.getTo())));
			}
		}
	}
	
	public void cityFromValueChanged(ValueChangeEvent event) throws Exception {
		cityToes = new ArrayList<SelectItem>();
		String from = (String) event.getNewValue();
		List<FlightLine> flightLines = flightLineDao.selectAll();
		for (FlightLine fl : flightLines) {
			if (from.equals(fl.getFrom().getId().toString())) {
				this.cityToes.add(new SelectItem(fl.getTo().getId().toString(),
						atsmUtils.translate(fl.getTo())));
			}
		}

		FacesContext context = FacesContext.getCurrentInstance();
		context.renderResponse();
	}

	private void setDefaultSeatCount(String planeID) {

		Plane newPlane = planeDao.find(Long.parseLong(planeID));
		seatCount = newPlane.getPlaneSeatCount();
	}

	public void planeValueChanged(ValueChangeEvent event) throws Exception {

		String planeID = (String) event.getNewValue();
		setDefaultSeatCount(planeID);
		FacesContext context = FacesContext.getCurrentInstance();
		context.renderResponse();
	}

	public String doUpdate() {
		if (!checkDate() || selectedFlightId < 0)
			return "fail";
		try {
			Plane plane = planeDao.find(Long.valueOf(selectedPlane));

			City from = cityDao.find(Long.valueOf(selectedCityFrom));
			City to = cityDao.find(Long.valueOf(selectedFlightLine));
			FlightLine flightLine = flightLineDao.selectFlightLineByFromAndTo(
					from, to);

			Flight flight = flightDao.find(selectedFlightId);
			if (flight == null) {
				return "fail";
			}
			flight.setFlightLine(flightLine);
			flight.setDepartDate(getSelectedDepartDate());
			flight.setArriveDate(getSelectedArriveDate());
			flight.setPlane(plane);
			flightDao.saveOrUpdate(flight);
			flightDao.flush();
			try {
				List<TicketType> ticketTypes = ticketTypeDao.selectAll();

				List<Ticket> tickets = ticketDao.selectWithinTicket(from, to,
						getSelectedDepartDate());
				if (tickets != null) {
					for (Ticket tk : tickets) {
						ticketDao.delete(tk);
					}
				}
				Ticket ticket1 = new Ticket(flight, ticketTypes.get(0),
						getTicketType1Price(), getTicketType1Quantity());
				Ticket ticket2 = new Ticket(flight, ticketTypes.get(1),
						getTicketType2Price(), getTicketType2Quantity());
				Ticket ticket3 = new Ticket(flight, ticketTypes.get(2),
						getTicketType3Price(), getTicketType3Quantity());
				Ticket ticket4 = new Ticket(flight, ticketTypes.get(3),
						getTicketType4Price(), getTicketType4Quantity());

				ticketDao.saveOrUpdate(ticket1);
				ticketDao.saveOrUpdate(ticket2);
				ticketDao.saveOrUpdate(ticket3);
				ticketDao.saveOrUpdate(ticket4);
			} catch (Exception exc) {
				return "fail";
			}
		} catch (Exception ex) {
			return "fail";
		}
		return "success";
	}

	private boolean checkDate() {
		if (getSelectedDepartDate() == null || getSelectedArriveDate() == null) {
			return false;
		}
		if (getSelectedDepartDate().before(Calendar.getInstance().getTime())) {
			return false;
		}
		if (getSelectedDepartDate().after(getSelectedArriveDate()))
			return false;
		return true;
	}

	public void createNew(String name) {
		modalPanelAction.show(name);
	}
	
	public String doSave(String name) {
		if (!checkDate())
			return "fail";
		try {
			Plane plane = planeDao.find(Long.valueOf(selectedPlane));

			City from = cityDao.find(Long.valueOf(selectedCityFrom));
			City to = cityDao.find(Long.valueOf(selectedFlightLine));
			FlightLine flightLine = flightLineDao.selectFlightLineByFromAndTo(
					from, to);

			Flight flight = new Flight(plane, flightLine,
					getSelectedDepartDate(), getSelectedArriveDate());
			flightDao.saveOrUpdate(flight);

			try {
				List<TicketType> ticketTypes = ticketTypeDao.selectAll();

				Ticket ticket1 = new Ticket(flight, ticketTypes.get(0),
						getTicketType1Price(), getTicketType1Quantity());
				Ticket ticket2 = new Ticket(flight, ticketTypes.get(1),
						getTicketType2Price(), getTicketType2Quantity());
				Ticket ticket3 = new Ticket(flight, ticketTypes.get(2),
						getTicketType3Price(), getTicketType3Quantity());
				Ticket ticket4 = new Ticket(flight, ticketTypes.get(3),
						getTicketType4Price(), getTicketType4Quantity());

				ticketDao.saveOrUpdate(ticket1);
				ticketDao.saveOrUpdate(ticket2);
				ticketDao.saveOrUpdate(ticket3);
				ticketDao.saveOrUpdate(ticket4);
				// ticket.
			} catch (Exception e) {
				log.debug("Co loi xay ra trong qua trinh tao ve chuyen bay.",
						e.getMessage());
				return "fail";
			}
		} catch (Exception e) {
			log.debug("Co loi xay ra trong qua trinh luu du lieu chuyen bay.",
					e.getMessage());
			return "fail";
		}

		flights = null;
		modalPanelAction.hide(name);
		return "success";
	}

	public String delete() {
		FacesContext context = FacesContext.getCurrentInstance();
		Map requestParams = context.getExternalContext().getRequestParameterMap();
		if (requestParams.containsKey("selectedFlightId")) {
			long id = Long.parseLong(requestParams.get("selectedFlightId").toString());
			Flight f = flightDao.find(id);
			f.setStatus("cancelled");
			flightDao.saveOrUpdate(f);
			context.addMessage("delete successful", new FacesMessage("abc"));
			return "success";
		}
		context.addMessage("delete fail", new FacesMessage("fail"));
		 
		return "fail";
	}

	public void setCityFroms(List<SelectItem> cityFroms) {
		this.cityFroms = cityFroms;
	}

	public List<SelectItem> getCityFroms() {
		return cityFroms;
	}

	public void setCityToes(List<SelectItem> cityToes) {
		this.cityToes = cityToes;
	}

	public List<SelectItem> getCityToes() {
		System.out.println(this.selectedCityFrom);
		System.out.println(this.selectedFlightLine);
		return cityToes;
	}

	public void setPlanes(List<SelectItem> planes) {
		this.planes = planes;
	}

	public List<SelectItem> getPlanes() {
		return planes;
	}

	public void setSelectedCityFrom(String selectedCityFrom) {
		this.selectedCityFrom = selectedCityFrom;
	}

	public String getSelectedCityFrom() {
		return selectedCityFrom;
	}

	public void setSelectedFlightLine(String selectedFlightLine) {
		this.selectedFlightLine = selectedFlightLine;
	}

	public String getSelectedFlightLine() {
		return selectedFlightLine;
	}

	public void setSelectedPlane(String selectedPlane) {
		this.selectedPlane = selectedPlane;
	}

	public String getSelectedPlane() {
		return selectedPlane;
	}

	public void setFlights(List<Flight> flights) {
		this.flights = flights;
	}

	public List<Flight> getFlights() {
		if (flights == null) {
			flights = flightDao.selectAll();
		}

		return flights;
	}

	public void setAtsmUtils(ATSMUtils atsmUtils) {
		this.atsmUtils = atsmUtils;
	}

	public ATSMUtils getAtsmUtils() {
		return atsmUtils;
	}

	/*
	 * public void setSelectedFlight(Flight selectedFlight) {
	 * this.selectedFlight = selectedFlight; }
	 * 
	 * public Flight getSelectedFlight() { return selectedFlight; }
	 */
	public void setSelectedDepartDate(Date selectedDepartDate) {
		this.selectedDepartDate = selectedDepartDate;
	}

	public Date getSelectedDepartDate() {
		return selectedDepartDate;
	}

	public void setSelectedArriveDate(Date selectedArriveDate) {
		this.selectedArriveDate = selectedArriveDate;
	}

	public Date getSelectedArriveDate() {
		return selectedArriveDate;
	}

	public void setTest(String test) {
		this.test = test;
	}

	public String getTest() {
		return test;
	}

	public void setTicketTypeName(List<String> ticketTypeName) {
		this.ticketTypeName = ticketTypeName;
	}

	public List<String> getTicketTypeName() {
		return ticketTypeName;
	}

	public void setTicketType1Quantity(int ticketType1Quantity) {
		this.ticketType1Quantity = ticketType1Quantity;
	}

	public int getTicketType1Quantity() {
		return ticketType1Quantity;
	}

	public void setTicketType2Quantity(int ticketType2Quantity) {
		this.ticketType2Quantity = ticketType2Quantity;
	}

	public int getTicketType2Quantity() {
		return ticketType2Quantity;
	}

	public void setTicketType3Quantity(int ticketType3Quantity) {
		this.ticketType3Quantity = ticketType3Quantity;
	}

	public int getTicketType3Quantity() {
		return ticketType3Quantity;
	}

	public void setTicketType4Quantity(int ticketType4Quantity) {
		this.ticketType4Quantity = ticketType4Quantity;
	}

	public int getTicketType4Quantity() {
		return ticketType4Quantity;
	}

	public void setSeatCount(int seatCount) {
		this.seatCount = seatCount;
	}

	public int getSeatCount() {
		return seatCount;
	}

	public void setTicketType1Price(long ticketType1Price) {
		this.ticketType1Price = ticketType1Price;
	}

	public long getTicketType1Price() {
		return ticketType1Price;
	}

	public void setTicketType2Price(long ticketType2Price) {
		this.ticketType2Price = ticketType2Price;
	}

	public long getTicketType2Price() {
		return ticketType2Price;
	}

	public void setTicketType3Price(long ticketType3Price) {
		this.ticketType3Price = ticketType3Price;
	}

	public long getTicketType3Price() {
		return ticketType3Price;
	}

	public void setTicketType4Price(long ticketType4Price) {
		this.ticketType4Price = ticketType4Price;
	}

	public long getTicketType4Price() {
		return ticketType4Price;
	}

	public List<Flight> getExpiredFlight() {
		return flightDao.selectExpiredFlight();
	}

	public List<Flight> getNewFlight() {
		return flightDao.selectNewFlight();
	}

	public List<Flight> getCancelledFlight() {
		return flightDao.selectCancelledFlight();
	}
}
